package com.foreverwin.jzymes.websocket;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foreverwin.jzymes.common.constant.Constants;
import com.foreverwin.jzymes.common.domain.YieldLog;
import com.foreverwin.jzymes.common.mapper.DashBoardAdviceMapper;
import com.foreverwin.jzymes.common.service.IActivityRuleAdviceService;
import com.foreverwin.jzymes.common.service.ICustomFieldsAdviceService;
import com.foreverwin.jzymes.common.service.IItemGroupAdviceService;
import com.foreverwin.jzymes.common.service.IProductionShiftService;
import com.foreverwin.jzymes.framework.annotation.WebSocketHandler;
import com.foreverwin.jzymes.framework.event.AppEvent;
import com.foreverwin.jzymes.framework.websocket.TextMessageWebSocketWraper;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@WebSocketHandler(channel = "Z_DB_YIELD_A")
public class AYieldHandler extends TextMessageWebSocketWraper {

    @Autowired
    IActivityRuleAdviceService activityRuleAdviceService;
    @Autowired
    IItemGroupAdviceService itemGroupAdviceService;
    @Autowired
    ICustomFieldsAdviceService customFieldsAdviceService;
    @Autowired
    IProductionShiftService productionShiftService;
    @Autowired
    DashBoardAdviceMapper dashBoardAdviceMapper;

    private Map<String,String> activityRuleMap;

    public AYieldHandler(){
        events = new ArrayList();
        events.add( "YIELD_REPORT" );
    }

    @Override
    public void doAfterOpen(Connection connection) {
        activityRuleMap = activityRuleAdviceService.findActivityRules( getChannel() );
    }

    @Override
    public void doAfterClose() {

    }

    @Override
    public JSONObject doReceiveAndReply(String messageType, JSONObject requestParams) {
        if( "WS_INIT_DATA".equals( messageType ) ){
            buildYieldReportData();
        }
        return null;
    }

    @Override
    public void onAppEvent(AppEvent<?> appEvent) {
        String event = appEvent.getName();
        if( "YIELD_REPORT".equals( event ) ){
            buildYieldReportData();
        }
    }

    public void buildYieldReportData(){
        String site = activityRuleMap.get( "SITE" );
        String[] operationList = activityRuleMap.get( "OPERATION" ).split( "," );
        String itemLabel = activityRuleMap.get( "ITEM_LABEL" );

        String itemGroup = itemGroupAdviceService.findItemGroupBySite( site );
        List<Map<String,Object>> itemMemeberList = itemGroupAdviceService.findItemGroupMember( site, itemGroup );
        String itemBo = null;
        for( Map<String,Object> itemMember : itemMemeberList ){
            String _itemBo = (String) itemMember.get( "ITEM_BO" );
            String _itemLabel = customFieldsAdviceService.findCustomValue( _itemBo, Constants.ITEM_CUSTOM_FIELD_ITEM_LABEL );
            if( itemLabel.equals( _itemLabel ) ){
                itemBo = _itemBo;
                break;
            }
        }

        String shift = productionShiftService.findShift( site, new Date() );
        Date[] dateRange = productionShiftService.findShiftRange( site, shift );

        JSONArray yieldData = new JSONArray();
        for( String operation : operationList ){
            JSONObject allSection = new JSONObject();
            allSection.put( "section", "all" );
            allSection.put( "type", operation );
            allSection.put( "input", 0L );
            allSection.put( "good", 0L );
            allSection.put( "rework", 0L );
            allSection.put( "abolish", 0L );
            yieldData.add( allSection );

            List<YieldLog> yieldLogList = dashBoardAdviceMapper.findYieldLogByDateRange( site, operation, itemBo, dateRange[0], dateRange[1] );
            for( YieldLog yieldLog : yieldLogList ){
                String section = activityRuleMap.get( yieldLog.getTimeRange() );
                JSONObject sectionObj = new JSONObject();
                sectionObj.put( "section", section );
                sectionObj.put( "type", operation );
                sectionObj.put( "input", yieldLog.getInputQty() );
                sectionObj.put( "good", yieldLog.getGoodQty() );
                sectionObj.put( "rework", yieldLog.getReworkQty() );
                sectionObj.put( "abolish", yieldLog.getScrapQty() );
                sectionObj.put( "oneYield", String.format( "%.2f%%", yieldLog.getFirstTimeYield() ) );
                sectionObj.put( "twoYield", String.format( "%.2f%%", yieldLog.getSecondTimeYield() ) );
                yieldData.add( sectionObj );

                allSection.put( "input", allSection.getLong( "input" ) + yieldLog.getInputQty() );
                allSection.put( "good", allSection.getLong( "good" ) + yieldLog.getGoodQty() );
                allSection.put( "rework", allSection.getLong( "rework" ) + yieldLog.getReworkQty() );
                allSection.put( "abolish", allSection.getLong( "abolish" ) + yieldLog.getScrapQty() );
            }

            if( allSection.getLong( "input" ) > 0 ){
                allSection.put( "oneYield", String.format( "%.2f%%", allSection.getBigDecimal( "good" ).divide( allSection.getBigDecimal( "input" ), 4, BigDecimal.ROUND_HALF_UP ).multiply( BigDecimal.valueOf( 100 ) ) ) );
                allSection.put( "twoYield", String.format( "%.2f%%", allSection.getBigDecimal( "good" ).add( allSection.getBigDecimal( "rework" ) ).divide( allSection.getBigDecimal( "input" ), 4, BigDecimal.ROUND_HALF_UP ).multiply( BigDecimal.valueOf( 100 ) ) ) );
            }
        }

        JSONObject response = new JSONObject();
        response.put( "itemLabel", itemLabel );
        response.put( "shift", shift );
        response.put( "data", yieldData );
        sendMessage( response );
    }
}
